package com.ych.modules.common.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.ych.modules.api.authorInfc.jackpot.service.JackpotService;
import com.ych.modules.base.dbEntity.TItemShowOrderEntity;
import com.ych.modules.base.dbEntity.TUserAccountChangeEntity;
import com.ych.modules.base.dbEntity.TUserAccountEntity;
import com.ych.modules.base.dbEntity.TUserItemEntity;
import com.ych.modules.base.service.ITItemShowOrderService;
import com.ych.modules.base.service.ITUserAccountChangeService;
import com.ych.modules.base.service.ITUserAccountService;
import com.ych.modules.base.service.ITUserItemService;
import com.ych.modules.common.service.ItemShowOrderService;
import com.ych.modules.common.service.UserItemService;
import com.ych.utils.DateUtils;
import com.ych.utils.TLMap;
import com.ych.utils.UUID;
import com.ych.utils.beanToMap.BeanMapUtil;
import com.ych.utils.mysqlPageUtil.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * Author: Usopp.tsui
 * Date: 2021/3/1
 * Time: 15:24
 * Description:
 */
@Service("ItemShowOrderService")
public class ItemShowOrderServiceImpl implements ItemShowOrderService {
    @Autowired
    private ITItemShowOrderService     itItemShowOrderService;
    @Autowired
    private ITUserItemService          itUserItemService;
    @Autowired
    private ITUserAccountService       itUserAccountService;
    @Autowired
    private ITUserAccountChangeService itUserAccountChangeService;
    @Autowired
    private JackpotService             jackpotService;
    @Autowired
    private UserItemService            userItemService;

    @Override
    @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void orderCreate(TItemShowOrderEntity orderEntity) {
        //参数校验
        this.validateCreateOrderParam(orderEntity);
        //校验账户余额是否充足
        this.validateUserAccount(orderEntity.getPayAmount());
        //创建订单
        orderEntity.setShowOrderId(UUID.randomUUID());
        orderEntity.setUserId(TLMap.getUserId());
        orderEntity.setCreateTime(new Date());
        orderEntity.setPayTime(new Date());
        orderEntity.setStatus("0");
        orderEntity.setRechargeStatusType("10003002");//直接就是交易成功
        itItemShowOrderService.insert(orderEntity);
        //用户账户变更记录
        this.addUserAccountChangeInfo(orderEntity);
        //用户账户金额扣除
        TUserAccountEntity accountEntity = new TUserAccountEntity();
        accountEntity.setUserId(TLMap.getUserId());
        accountEntity.setGoldCoinAmount(orderEntity.getPayAmount().negate());
        itUserAccountService.updateByEntity(accountEntity);
        //将金币按比例写入奖池
        try {
            //支付金额就是要分到奖池的金额
            BigDecimal amount = orderEntity.getPayAmount();
            switch (orderEntity.getShowType()) {
                case "10009001"://轮播
                    //10012003：轮播发布
                    jackpotService.addAmountToJackpot("10012003", amount, orderEntity.getShowOrderId(), null);
                    break;
                case "10009002"://固定头条
                    //10012004：固定头条发布
                    jackpotService.addAmountToJackpot("10012004", amount, orderEntity.getShowOrderId(), null);
                    break;
                default:
                    return;
            }

        } catch (Exception e) {
            //不阻断正常流程
        }
    }

    @Override
    public void decreaseCarouselItem(String orderId) {
        TItemShowOrderEntity orderEntity = itItemShowOrderService.selectById(orderId);
        if (null == orderEntity) {
            throw new RuntimeException("递减单号错误");
        }
        Wrapper<TItemShowOrderEntity> wrapper = new EntityWrapper<TItemShowOrderEntity>()
                .where("1=1")
                .eq("show_order_id", orderId);
        //递减
        itItemShowOrderService.updateForSet("show_times_count = show_times_count -1", wrapper);
    }

    @Override
    public List<TItemShowOrderEntity> listCarouselItem() {
        TItemShowOrderEntity entity = new TItemShowOrderEntity();
        entity.setPage(1);
        entity.setLimit(6);//轮播六个就行了
        Wrapper<TItemShowOrderEntity> wrapper = new EntityWrapper<TItemShowOrderEntity>()
                .where("1=1")
                .eq("status", "0")
                .eq("recharge_status_type", "10003002")//交易成功
                .gt("show_times_count", 0)//次数大于0
                .orderBy("create_time asc");
        Page<TItemShowOrderEntity> page = itItemShowOrderService.selectPage(new Query<TItemShowOrderEntity>(BeanMapUtil.toPageQuery(entity)).getPage(), wrapper);
        for (TItemShowOrderEntity orderEntity : page.getRecords()) {
            TUserItemEntity itemEntity = userItemService.getUserItem(orderEntity.getBusinessId());
            orderEntity.setItemEntity(itemEntity);
        }
        return page.getRecords();
    }

    @Override
    public List<TItemShowOrderEntity> listFixedHeadlineItem() {
        Integer showCount = 24;//暂时多少个固定头条，默认24个
        Wrapper<TItemShowOrderEntity> wrapper = new EntityWrapper<TItemShowOrderEntity>()
                .where("show_start_time is not null")
                .eq("status", "0")
                .eq("show_type", "10009002")//固定头条
                .eq("recharge_status_type", "10003002")//交易成功
                .gt("show_end_time", new Date())//最后时间大于当前时间
                .orderBy("create_time asc");
        List<TItemShowOrderEntity> list = itItemShowOrderService.selectList(wrapper);
        //不足10个，需要补充的数量
        Integer replenishCount = null == list ? showCount : showCount - list.size();
        //已经够了，直接返回
        if (replenishCount <= 0) {
            for (TItemShowOrderEntity orderEntity : list) {
                TUserItemEntity itemEntity = userItemService.getUserItem(orderEntity.getBusinessId());
                orderEntity.setItemEntity(itemEntity);
            }
            return list;
        }
        //查询出来更多的补偿上来
        TItemShowOrderEntity entity = new TItemShowOrderEntity();
        entity.setPage(1);
        entity.setLimit(replenishCount);
        Wrapper<TItemShowOrderEntity> orderWrapper = new EntityWrapper<TItemShowOrderEntity>()
                .where("show_start_time is null")
                .eq("status", "0")
                .eq("show_type", "10009002")//固定头条
                .eq("recharge_status_type", "10003002")//交易成功
                .orderBy("create_time asc");
        Page<TItemShowOrderEntity> page = itItemShowOrderService.selectPage(new Query<TItemShowOrderEntity>(BeanMapUtil.toPageQuery(entity)).getPage(), orderWrapper);
        for (TItemShowOrderEntity orderEntity : page.getRecords()) {
            //处理固定头条项目开始投放
            this.dealFixedHeadlineItem(orderEntity);
            list.add(orderEntity);
        }
        for (TItemShowOrderEntity orderEntity : list) {
            TUserItemEntity itemEntity = userItemService.getUserItem(orderEntity.getBusinessId());
            orderEntity.setItemEntity(itemEntity);
        }
        return list;
    }

    /**
     * 处理固定头条项目开始投放
     *
     * @param orderEntity
     */
    private void dealFixedHeadlineItem(TItemShowOrderEntity orderEntity) {
        orderEntity.setShowStartTime(new Date());
        Date endTime = DateUtils.addDateDays(orderEntity.getShowStartTime(), orderEntity.getShowDaysCount());
        orderEntity.setShowEndTime(endTime);
        itItemShowOrderService.updateById(orderEntity);
    }

    /**
     * 用户账户变更记录添加
     *
     * @param orderEntity
     */
    private void addUserAccountChangeInfo(TItemShowOrderEntity orderEntity) {
        TUserAccountEntity accountEntity = itUserAccountService.selectById(orderEntity.getUserId());
        TUserAccountChangeEntity changeEntity = new TUserAccountChangeEntity();
        changeEntity.setChangeId(UUID.randomUUID());
        changeEntity.setUserId(orderEntity.getUserId());
        changeEntity.setAccountTrend("10000002");//支出
        changeEntity.setBusinessId(orderEntity.getShowOrderId());
        changeEntity.setAccountChangeBusinessType("10001003");//10001003轮播/固定头条订单
        //现金
        changeEntity.setCashAmount(BigDecimal.ZERO);
        changeEntity.setBeforeCashAmount(accountEntity.getCashAmount());
        changeEntity.setAfterCashAmount(accountEntity.getCashAmount());
        //金币
        changeEntity.setGoldCoinAmount(orderEntity.getPayAmount());
        changeEntity.setBeforeGoldCoinAmount(accountEntity.getGoldCoinAmount());
        changeEntity.setAfterGoldCoinAmount(accountEntity.getGoldCoinAmount().subtract(orderEntity.getPayAmount()));
        //抽奖券
        changeEntity.setRaffleTicket(0);
        changeEntity.setBeforeRaffleTicket(accountEntity.getRaffleTicket());
        changeEntity.setAfterRaffleTicket(accountEntity.getRaffleTicket());

        changeEntity.setCreateTime(new Date());

        itUserAccountChangeService.insert(changeEntity);
    }

    /**
     * 校验账户余额是否充足
     *
     * @param payAmount
     */
    private void validateUserAccount(BigDecimal payAmount) {
        TUserAccountEntity accountEntity = itUserAccountService.selectById(TLMap.getUserId());
        if (payAmount.compareTo(accountEntity.getGoldCoinAmount()) > 0) {
            throw new RuntimeException("账户金币余额不足，请先购置金币");
        }
    }

    /**
     * 创建订单参数校验
     *
     * @param orderEntity
     */
    private void validateCreateOrderParam(TItemShowOrderEntity orderEntity) {
        //校验广告是否存在
        TUserItemEntity itemEntity = itUserItemService.selectById(orderEntity.getBusinessId());
        if (null == itemEntity) {
            throw new RuntimeException("项目不存在，请选择正确的项目");
        }
        if (orderEntity.getPayAmount().compareTo(BigDecimal.ZERO) < 0) {
            throw new RuntimeException("非法请求！");
        }
        //轮播10009001，固定头条10009002
        switch (orderEntity.getShowType()) {
            case "10009001"://轮播10009001
                //必传参数校验
                if (null == orderEntity.getShowTimesCount() || orderEntity.getShowTimesCount() <= 0) {
                    throw new RuntimeException("请选择正确的展示次数！");
                }
                break;
            case "10009002"://固定头条10009002
                //必传参数校验
                if (null == orderEntity.getShowDaysCount() || orderEntity.getShowDaysCount() <= 0) {
                    throw new RuntimeException("请选择正确的展示天数！");
                }
                break;
            default:
                throw new RuntimeException("未知类型");
        }
    }
}
